/////////////////////////////////////
////// KECE343 Project 3 ////////////
////// Multiplier by 2009170912 /////
//////Park, Seong Joon //////////////
/////////////////////////////////////

`timescale 1ns/1ns

module multiplier(
iClk, // input clock
iReset, // reset signal
iReady, // indicates inputs are ready
oDone, // indicates that the result is ready
iMultiplier, // 8-bit multiplier [7:0]
iMultiplicand, // 8-bit multiplicand [7:0]
oProduct // 16-bit product [15:0]
);
input [7:0] iMultiplier;
input [7:0] iMultiplicand;
input iClk;
input iReset;
input iReady;

output oDone;
output [15:0] oProduct;

reg [15:0] oProduct;
reg oDone=0;

reg [2:0]counter; //counter for 8
reg c_cin=0, c_cout=0;
reg enable=0;
reg c=0, cout=0;

initial begin
counter=3'b000; //counter to zero
oProduct={8'b0000_0000,iMultiplier[7:0]}; //preparing 16bit product bit
end

//Reset control//
always @ (iReset) begin
oProduct<=0;
oDone<=0;
end

//Multipling Control//
always @ ( posedge iClk & !(oDone) & iReady & !(iReset)) //do following insn(s) when adding finished(&positive edge)
begin

if(oProduct[0]) begin //if it needs to add..

cout=c&(oProduct[8]|iMultiplicand[0])|(oProduct[8]&iMultiplicand[0]);
oProduct[8]=oProduct[8]^iMultiplicand[0]^c;
c=cout;

cout=c&(oProduct[9]|iMultiplicand[1])|(oProduct[9]&iMultiplicand[1]);
oProduct[9]=oProduct[9]^iMultiplicand[1]^c;
c=cout;

cout=c&(oProduct[10]|iMultiplicand[2])|(oProduct[10]&iMultiplicand[2]);
oProduct[10]=oProduct[10]^iMultiplicand[2]^c;
c=cout;

cout=c&(oProduct[11]|iMultiplicand[3])|(oProduct[11]&iMultiplicand[3]);
oProduct[11]=oProduct[11]^iMultiplicand[3]^c;
c=cout;

cout=c&(oProduct[12]|iMultiplicand[4])|(oProduct[12]&iMultiplicand[4]);
oProduct[12]=oProduct[12]^iMultiplicand[4]^c;
c=cout;

cout=c&(oProduct[13]|iMultiplicand[5])|(oProduct[13]&iMultiplicand[5]);
oProduct[13]=oProduct[13]^iMultiplicand[5]^c;
c=cout;

cout=c&(oProduct[14]|iMultiplicand[6])|(oProduct[14]&iMultiplicand[6]);
oProduct[14]=oProduct[14]^iMultiplicand[6]^c;
c=cout;

cout=c&(oProduct[15]|iMultiplicand[7])|(oProduct[15]&iMultiplicand[7]);
oProduct[15]=oProduct[15]^iMultiplicand[7]^c;
c=cout;

oProduct={c,oProduct[15:1]};
end

else begin //if it doesn't need to add..
oProduct<={1'b0, oProduct[15:1]}; //just right shift
end

if(counter==7) //if counter reaches 7
oDone<=1; //oDone flag to 1

//counting : add 001 //

c_cout=c_cin&(counter[0]|1'b1)|(counter[0]&1'b1);
counter[0]=counter[0]^1'b1^c_cin;
c_cin=c_cout;

c_cout=c_cin&(counter[1]|1'b0)|(counter[0]&1'b0);
counter[1]=counter[1]^1'b0^c_cin;
c_cin=c_cout;

c_cout=c_cin&(counter[2]|1'b0)|(counter[0]&1'b0);
counter[2]=counter[2]^1'b0^c_cin;
c_cin=c_cout;


end


endmodule

